package com.chen.authority.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.chen.authority.common.model.PageQo;
import com.chen.authority.common.response.Response;
import com.chen.authority.common.util.WrapperUtil;
import com.chen.authority.mapper.DictDataMapper;
import com.chen.authority.mapper.DictTypeMapper;
import com.chen.authority.model.dto.DictTypeDto;
import com.chen.authority.model.po.DictDataPo;
import com.chen.authority.model.po.DictTypePo;
import com.chen.authority.model.qo.DictTypeQo;
import com.chen.authority.model.vo.DictTypeVo;
import com.chen.authority.service.DictTypeService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 字典类型 Service业务层处理
 *
 * @author chengy
 * @date 2023-09-04
 */
@Service
@RequiredArgsConstructor
public class DictTypeServiceImpl extends ServiceImpl<DictTypeMapper, DictTypePo> implements DictTypeService {

    private final DictDataMapper dictDataMapper;

    @Override
    public Page<DictTypeVo> pageQueryDictTypeList(PageQo pageQo, DictTypeQo dictTypeQo) {
        return baseMapper.selectVoPage(pageQo.build(), WrapperUtil.buildQueryWrapper(dictTypeQo));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Response addOrUpdateDictType(Integer id, DictTypeDto dto) {
        boolean exists = baseMapper.exists(Wrappers.<DictTypePo>lambdaQuery()
                .and(sql -> sql.eq(DictTypePo::getName, dto.getName())
                        .or()
                        .eq(DictTypePo::getType, dto.getType()))
                .ne(ObjectUtil.isNotNull(id), DictTypePo::getId, id));
        if (exists) {
            return Response.fail("名称或类型重复，请检查");
        }
        // 更新冗余字段
        if (ObjectUtil.isNotNull(id)) {
            dictDataMapper.update(null, Wrappers.<DictDataPo>lambdaUpdate()
                    .eq(DictDataPo::getType, baseMapper.selectById(id).getType())
                    .set(DictDataPo::getType, dto.getType()));
        }
        DictTypePo dictType = dto.toPo(DictTypePo.class);
        dictType.setId(id);
        return this.saveOrUpdate(dictType) ? Response.success() : Response.fail();
    }

    @Override
    public Response deleteDictTypeByIds(List<Integer> ids) {
        List<String> types = baseMapper.selectBatchIds(ids)
                .stream()
                .map(DictTypePo::getType)
                .collect(Collectors.toList());
        boolean exists = dictDataMapper.exists(Wrappers
                .<DictDataPo>lambdaQuery()
                .in(DictDataPo::getType, types));
        if (exists) {
            return Response.fail("存在已分配的数据字典，无法删除");
        }
        return this.removeByIds(ids) ? Response.success() : Response.fail();
    }

    @Override
    public List<DictTypeVo> exportDictTypeList(QueryWrapper<DictTypePo> queryWrapper) {
        return baseMapper.selectVoList(queryWrapper);
    }

}